using System;
using System.IO;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;

namespace ShuttleBus.Serialization
{
    public class JsonSerializer : ISerializer
    {
        private readonly Newtonsoft.Json.JsonSerializer _serializer;

        public JsonSerializer()
        {
            _serializer = new Newtonsoft.Json.JsonSerializer();
        }

        public void Serialize(IStream stream, TransportMessage objectToSerialize)
        {
            var writer = new StreamWriter(stream.BaseStream);
            _serializer.Serialize(writer, objectToSerialize);
            writer.Flush();
            stream.BaseStream.Position = 0;
        }

        public object Deserialize(IStream stream)
        {
            var streamReader = new StreamReader(stream.BaseStream);
            var messageWrapper = (TransportMessage)_serializer.Deserialize(streamReader, typeof(TransportMessage));

            var methodInfo = _serializer.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(m => m.Name == "Deserialize" && m.IsGenericMethod);
            var genericMethod = methodInfo.MakeGenericMethod(Type.GetType(messageWrapper.Type));

            return genericMethod.Invoke(_serializer, new[] { new JsonTextReader(new StringReader(messageWrapper.Payload.ToString())) });
        }
    }
}